package eteam.aps.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import eteam.aps.api.U8Api;
import eteam.aps.client.CommonClient;
import eteam.aps.common.component.GetOrderNumber;
import eteam.aps.common.component.LoginUserRedisService;
import eteam.aps.common.constant.OrderType;
import eteam.aps.common.constant.ProductType;
import eteam.aps.common.entity.ParentEntity;
import eteam.aps.common.exceptions.BusinessException;
import eteam.aps.common.helper.Helper;
import eteam.aps.common.helper.JsonPage;
import eteam.aps.mapper.*;
import eteam.aps.model.dto.SaleOrderQueryDto;
import eteam.aps.model.dto.SalesOrderDisDto;
import eteam.aps.model.dto.SalesOrderUpdateDto;
import eteam.aps.model.entity.SalesAudit;
import eteam.aps.model.entity.SalesGood;
import eteam.aps.model.entity.SalesOrder;
import eteam.aps.model.entity.other.SalesOrderBody;
import eteam.aps.model.entity.other.SalesOrderHead;
import eteam.aps.model.entity.other.SalesOrderSave;
import eteam.aps.model.entity.sale.SaleOrderBll;
import eteam.aps.model.entity.sale.SaleOrderScan;
import eteam.aps.model.vo.moco_rders.MocoRdersBordyVo;
import eteam.aps.model.vo.sale.SaleOrderScanDto;
import eteam.aps.model.vo.sales_order.SaleOrderQueryVo;
import eteam.aps.model.vo.sales_order.SalesOrderShow;
import eteam.aps.model.vo.sales_order.SalesOrderVo;
import eteam.aps.service.SalesOrderService;
import eteam.aps.systeminterface.model.vo.Worksheets;
import eteam.aps.zn.ZNApiConstant;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;

/**
 * 销售订单 业务实现类
 *
 * @author LiuLei
 */
@Service
public class SalesOrderServiceImpl implements SalesOrderService {

    @Autowired
    private SalesOrderMapper salesOrderMapper;

    @Autowired
    private SaleScanMapper saleScanMapper;

    @Autowired
    private LoginUserRedisService loginUserRedisService;

    @Autowired
    private CommonClient commonClient;

    @Autowired
    private ProductNumberMapper productNumberMapper;

    @Autowired
    private MocoRdersMapper mocoRdersMapper;

    @Autowired
    private MocoRdersBordyMapper mocoRdersBordyMapper;

    @Autowired
    private SalesAuditMapper salesAuditMapper;

    @Autowired
    private SaleOrderBllMapper saleOrderBllMapper;

    @Autowired
    private SaleOrderScanMapper saleOrderScanMapper;

    @Override
    public SalesOrderSave getCustomerByOrderCode(String orderCode) throws Exception {
        if (Helper.isEmpty(orderCode))
            throw new BusinessException(HttpStatus.BAD_REQUEST, "订单编号不能为空！");
        Map<String, Object> map = new HashMap<>();
        map.put("code", orderCode);
        map.put("state", ParentEntity.FSTATE_DELETED);
        List<SalesOrderDisDto> list = salesOrderMapper.selectOrderLisByOrderCode(map);
        SalesOrderSave salesOrder = U8Api.getSalesOrder(orderCode);
        if (list.isEmpty()) return salesOrder;
        if (salesOrder == null)
            throw new BusinessException(HttpStatus.BAD_REQUEST, "暂无数据！");
        List<SalesOrderBody> sal = salesOrder.getSalesOrderBodyList();
        List<SalesOrderBody> reSet = new LinkedList<>();
        for (SalesOrderBody body : sal) {
            boolean flag = true;
            for (SalesOrderDisDto disDto : list) {
                if (body.getfInvCode().equals(disDto.getfInvCode()) &&
                        body.getfRowNum() == disDto.getfRowNum()) {
                    flag = false;
                    break;
                }
            }
            if (flag) reSet.add(body);
        }
        // 过滤掉物料相同的
        salesOrder.setSalesOrderBodyList(reSet);
        return salesOrder;
    }

    @Override
    public Integer delBySalesOrderByFId(String fId) {
        int count = salesOrderMapper.selCountByOrderState(fId, OrderType.DRAFT);
        if (count == 0) throw new BusinessException("不是草稿状态，不能删除！");
        return salesOrderMapper.delBySalesOrderByFId(fId);
    }

    @Override
    public SalesOrderBody getInvByInvCode(String invCode) {
        Map<String, Object> map = new HashMap<>();
        map.put("invCode", invCode);
        map.put("state", ParentEntity.FSTATE_DELETED);
        SalesOrderBody salesOrderBody = salesOrderMapper.selectOneByInvCode(map);
        if (salesOrderBody == null) throw new BusinessException("暂无数据！");
        return salesOrderBody;
    }

    @Override
    @Transactional
    public int saveCustomerOrder(SalesOrderSave salesOrderSave) throws Exception {
        // 获取用户信息
        String fuserid = loginUserRedisService.getUser().getFuserid();
        // 获取单别信息
        Worksheets worksheets = commonClient.selectSheetPrefix(ZNApiConstant.ORC);
        // 获取起始单号
        String orderNumber = GetOrderNumber.getOrderNumber(worksheets, salesOrderMapper.selectMaxWorkOrderNumber());
        SalesOrderHead head = salesOrderSave.getSalesOrderHead();
        String orderCode = head.getfOrderCode();
        List<SalesOrder> orderList = new LinkedList<>();
        if (Helper.isEmpty(orderCode)) {
            int num = 1;
            // 获取销售订单信息
            for (SalesOrderBody salesOrderBody : salesOrderSave.getSalesOrderBodyList()) {
                SalesOrder salesOrder = BeanUtil.copyProperties(salesOrderSave.getSalesOrderHead(), SalesOrder.class);
                salesOrder.setfOrderDate(LocalDate.now()); // 单据日期
                salesOrder.setfDate(LocalDate.now());//单据日期
                salesOrder.setfOrderNumber(orderNumber); // 单号
                salesOrder.setfWorksheetCode(ZNApiConstant.ORC); // 单别
                salesOrder.setfWorksheetName("销售单"); // 单别名称
                salesOrder.setfOrderState(OrderType.DRAFT); // 订单状态
                salesOrder.setfRowNum(num++); // 序号
                salesOrder.setfInvCode(salesOrderBody.getfInvCode()); // 物料编号
                salesOrder.setfInvName(salesOrderBody.getfInvName()); // 物料名称
                salesOrder.setfInvStd(salesOrderBody.getfInvStd()); // 物料规格
                salesOrder.setfUnitName(salesOrderBody.getfUnitName());// 销售单位
                salesOrder.setfOrderNum(salesOrderBody.getfOrderNum()); // 订货数
                salesOrder.setfUnitPrice(salesOrderBody.getfUnitPrice()); // 单价
                salesOrder.setfQuotedPrice(salesOrderBody.getfQuotedPrice()); // 报价
                salesOrder.setfTaxUnitPrice(salesOrderBody.getfTaxUnitPrice()); // 含税单价
                salesOrder.setfTaxRate(salesOrderBody.getfTaxRate()); // 税率
                salesOrder.setfMoney(salesOrderBody.getfMoney()); // 无税金额
                salesOrder.setfSum(salesOrderBody.getfSum()); // 税价合计
                salesOrder.setfSendNum(salesOrderBody.getfSendNum()); // 发货数
                salesOrder.setfScanNum(salesOrderBody.getfScanNum()); // 扫描数
                // 填充默认值
                Helper.setDefaultAddValue(salesOrder, fuserid);
                orderList.add(salesOrder);
            }
        } else {
            // 获取销售订单信息
            Map<String, SaleOrderQueryVo> order = U8Api.getSaleOrder(salesOrderSave.getSalesOrderHead().getfOrderCode());
            for (SalesOrderBody salesOrderBody : salesOrderSave.getSalesOrderBodyList()) {
                SalesOrder salesOrder = BeanUtil.copyProperties(salesOrderSave.getSalesOrderHead(), SalesOrder.class);
                String invCode = salesOrderBody.getfInvCode();
                SaleOrderQueryVo queryVo = order.get(invCode);
                salesOrder.setfAuditId(queryVo.getAutoId()); // 销售订单字表Id
                salesOrder.setfOrderDate(LocalDate.now()); // 单据日期
                salesOrder.setfDate(LocalDate.now());//单据日期
                salesOrder.setfOrderNumber(orderNumber); // 单号
                salesOrder.setfWorksheetCode(ZNApiConstant.ORC); // 单别
                salesOrder.setfWorksheetName("销售单"); // 单别名称
                salesOrder.setfOrderState(OrderType.DRAFT); // 订单状态
                salesOrder.setfRowNum(queryVo.getRowNum()); // 序号
                salesOrder.setfInvCode(salesOrderBody.getfInvCode()); // 物料编号
                salesOrder.setfInvName(salesOrderBody.getfInvName()); // 物料名称
                salesOrder.setfInvStd(salesOrderBody.getfInvStd()); // 物料规格
                salesOrder.setfUnitName(salesOrderBody.getfUnitName());// 销售单位
                salesOrder.setfOrderNum(salesOrderBody.getfOrderNum()); // 订货数
                salesOrder.setfUnitPrice(salesOrderBody.getfUnitPrice()); // 单价
                salesOrder.setfQuotedPrice(salesOrderBody.getfQuotedPrice()); // 报价
                salesOrder.setfTaxUnitPrice(salesOrderBody.getfTaxUnitPrice()); // 含税单价
                salesOrder.setfTaxRate(salesOrderBody.getfTaxRate()); // 税率
                salesOrder.setfMoney(salesOrderBody.getfMoney()); // 无税金额
                salesOrder.setfSum(salesOrderBody.getfSum()); // 税价合计
                salesOrder.setfSendNum(salesOrderBody.getfSendNum()); // 发货数
                salesOrder.setfScanNum(salesOrderBody.getfScanNum()); // 扫描数
                // 填充默认值
                Helper.setDefaultAddValue(salesOrder, fuserid);
                orderList.add(salesOrder);
            }
        }
        return salesOrderMapper.saveCustomerOrder(orderList);
    }

    @Override
    public JsonPage<SalesOrderVo> getSalesOrderByQuery(SaleOrderQueryDto saleOrderQueryDto) {
        Helper.setEmptyWithNull(saleOrderQueryDto);
        Map<String, Object> map = new HashMap<>(7);
        map.put("orderState", saleOrderQueryDto.getState());
        map.put("fState", ParentEntity.FSTATE_DELETED);
        if (saleOrderQueryDto.getDate() != null)
            map.put("date", saleOrderQueryDto.getDate());
        if (Helper.isNotEmpty(saleOrderQueryDto.getCustomerCode()))
            map.put("customerCode", Helper.likeSql(saleOrderQueryDto.getCustomerCode()));
        if (Helper.isNotEmpty(saleOrderQueryDto.getCustomerName()))
            map.put("customerName", Helper.likeSql(saleOrderQueryDto.getCustomerName()));
        if (Helper.isNotEmpty(saleOrderQueryDto.getOrderCode()))
            map.put("orderCode", saleOrderQueryDto.getOrderCode());
        if (Helper.isNotEmpty(saleOrderQueryDto.getSendAddress()))
            map.put("address", Helper.likeSql(saleOrderQueryDto.getSendAddress()));
        if (saleOrderQueryDto.getState() != null)
            map.put("state", saleOrderQueryDto.getState());
        int count = salesOrderMapper.selCountSalesOrderByQuery(map);
        if (count == 0) return JsonPage.builder(saleOrderQueryDto.getPage(),
                saleOrderQueryDto.getSize(), count, Collections.emptyList());
        map.put("offSize", saleOrderQueryDto.offSize());
        map.put("pageSize", saleOrderQueryDto.getSize());
        List<SalesOrderVo> list = salesOrderMapper.getSalesOrderByQuery(map);
        return JsonPage.builder(saleOrderQueryDto.getPage(),
                saleOrderQueryDto.getSize(), count, list);
    }

    @Override
    @Transactional
    public List<SalesOrder> scanSalesOrder(String scan) throws Exception {
        Map<String, Object> map = new HashMap<>();
        map.put("scan", scan);
        map.put("state", ParentEntity.FSTATE_DELETED);
        map.put("start", OrderType.DRAFT);
        map.put("end", OrderType.SCAN);
        List<SalesOrder> orderList = salesOrderMapper.selectList(map);
        if (orderList.isEmpty()) throw new BusinessException("暂无数据！");
        return orderList;
//        if (!salesOrderList.isEmpty()) {
//            if (salesOrderList.get(0).getfOrderState() == OrderType.DRAFT) { // 未扫描
//                Map<String, Object> uso = new HashMap<>(4);
//                uso.put("scan", scan);
//                uso.put("state", OrderType.SCAN);
//                uso.put("modify", loginUserRedisService.getUser().getFuserid());
//                uso.put("time", LocalDateTime.now());
//                salesOrderMapper.updateSalesOrderOrderState(uso);
//            }
//            return salesOrderList;
//        }
    }

    @Override
    @Transactional
    public String addDelivery(Map<String, Object> map) throws Exception {
        JSONObject u8 = U8Api.formatTime(map);
        List<SalesGood> goodList = new LinkedList<>();
        JSONArray goods = u8.getJSONArray("data");
        String str = goods.getJSONObject(0).getJSONArray("Rows").getJSONObject(0).getStr("orderNumber");
        //没有订单编号
        if (StrUtil.isEmpty(str)) return null;
        List<String> invLis = new LinkedList<>();
        if (!goods.isEmpty()) {
            goods.forEach(data -> {
                JSONObject good = (JSONObject) data;
                for (Object rows : good.getJSONArray("Rows")) {
                    JSONObject row = (JSONObject) rows;
                    invLis.add(row.getStr("cInvCode"));
                    goodList.add(new SalesGood(row.getStr("orderNumber"),
                            row.getInt("iOrderRowNo"), row.getStr("mocCode")));
                }
            });
        }
        List<MocoRdersBordyVo> list = mocoRdersBordyMapper.getByInvs(invLis);
        Map<String, MocoRdersBordyVo> inv = new HashMap<>(list.size());
        list.forEach(data -> inv.put(data.getfInvCode(), data));
        JSONArray data = u8.getJSONArray("data");
        for (Object datum : data) {
            JSONObject da = (JSONObject) datum;
            JSONArray array = da.getJSONArray("Rows");
            JSONArray jsonArray = new JSONArray();
            for (Object entry : array) {
                JSONObject obj = JSONUtil.parseObj(entry);
                MocoRdersBordyVo bordyVo = inv.get(obj.getStr("cInvCode"));
                if (bordyVo != null) {
                    obj.putOpt("cWhCode", bordyVo.getfWhCode());
                }
                jsonArray.add(obj);
            }
            da.set("Rows", jsonArray);
        }
        // 新增一张发货单
        // todo 这里不在调用u8接口 只做本地保存修改状态
        JSONArray ds = u8.getJSONArray("data");
        String tradeid = "不调用U8接口，修改状态发货状态";
//        String tradeid = U8Api.ptsDispatchList(ds.toString());
        if (Helper.isNotEmpty(tradeid) && !goodList.isEmpty()) {
            String fuserid = loginUserRedisService.getUser().fuserid;
            LocalDateTime now = LocalDateTime.now();
//            Set<SalesAudit> auditList = new HashSet<>();
            for (SalesGood salesGood : goodList) {
                salesGood.setfSaleOrder(tradeid);
                SalesAudit audit = new SalesAudit(
                        tradeid, salesGood.getfOrderNumber()
                );
                Helper.setDefaultAddValue(salesGood, fuserid);
                Helper.setDefaultAddValue(audit, fuserid);
//                auditList.add(audit);
            }
            // 保存销售发货单记录
            if (!goods.isEmpty()) salesOrderMapper.addSalesGood(goodList);
            // 新增发货单审核记录(不需要)
//            if (!auditList.isEmpty()) salesAuditMapper.insertSalesAudit(auditList);
            // 修改销售订单状态 (入库)
            String orderNumber = goodList.get(0).getfOrderNumber();
            Map<String, Object> uso = new HashMap<>(4);
            uso.put("scan", orderNumber);
            uso.put("state", OrderType.DELIVERY);
            uso.put("modify", fuserid);
            uso.put("time", LocalDateTime.now());
            // 修改产品状态 (入库)
            List<Map<String, Object>> mapList = new LinkedList<>();
            goodList.forEach(res -> {
                Map<String, Object> mp = new HashMap<>(6);
                mp.put("processing", ProductType.DELIVERY);
                mp.put("modify", fuserid);
                mp.put("time", now);
                mp.put("bar", res.getfMocCode());
                mp.put("orderCode", res.getfOrderNumber());
                mp.put("orderNumber", tradeid);
                mapList.add(mp);
            });
            // 修改订单记录表的销售订单号
            saleScanMapper.updateSaleNumBySaleOrder(orderNumber, tradeid);
            productNumberMapper.batchUpdateProTypeByBarCode(mapList);
            salesOrderMapper.updateSalesOrderOrderState(uso);
        }
        return tradeid;
    }

//    @Override
//    @Transactional
//    public MocoRdersSaleVo scanProductNum(String saleOrder, String scan) throws Exception {
//        Map<String, Object> map = new HashMap<>(4);
//        map.put("fState", ParentEntity.FSTATE_DELETED);
//        map.put("code", scan);
//        map.put("start", ProductType.STORAGE);
//        map.put("end", ProductType.SCAN);
//        MocoRdersSaleVo displayVo = mocoRdersMapper.selMocByProOrderBarCode(map);
//        if (displayVo == null) throw new BusinessException(HttpStatus.BAD_REQUEST, "暂无扫描数据！");
//        SaleScan saleScan = new SaleScan();
//        saleScan.setfSaleOrder(saleOrder);
//        saleScan.setfProductCode(displayVo.getfSnBarCode());
//        saleScan.setfSaleStat(SaleScanType.SCAN);
//        saleScan.setfInvCode(displayVo.getfInvCode());
//        Helper.setDefaultAddValue(saleScan, loginUserRedisService.getUser().getFuserid());
//        saleScanMapper.save(saleScan);
//        return displayVo;
//    }

    /**
     * @since 2025/05/20
     */
    @Override
    @Transactional
    public void scanProductNum(SaleOrderScanDto scan) throws Exception {
        Integer count = saleOrderScanMapper.selectCount(
                Wrappers.<SaleOrderScan>lambdaQuery()
                        .eq(SaleOrderScan::getfBarCode, scan.getfBarCode())
        );
        if (count > 0) throw new BusinessException(String.format("已存在%s的扫描记录！", scan.getfBarCode()));
        // 查询是否可以扫描
        SaleOrderBll bll = saleOrderBllMapper.selectOne(
                Wrappers.<SaleOrderBll>lambdaQuery()
                        .select(
                                SaleOrderBll::getfSendNum,
                                SaleOrderBll::getfScanNum
                        )
                        .eq(SaleOrderBll::getfDtlId, scan.getfSaleOrderCode())
                        .eq(SaleOrderBll::getfSeqNo, scan.getfSeqNo())
        );
        if (bll == null) throw new BusinessException("暂无扫描信息！");
        if (bll.getfScanNum() != null && bll.getfScanNum().compareTo(bll.getfSendNum()) >= 0) {
            throw new BusinessException("扫描数量不能超出发货数量！");
        }
        String fuserid = loginUserRedisService.getUser().getFuserid();
        SaleOrderScan saleOrderScan = new SaleOrderScan();
        saleOrderScan.setfSaleOrderCode(scan.getfSaleOrderCode());
        saleOrderScan.setfBarCode(scan.getfBarCode());
        saleOrderScan.setfSepNo(scan.getfSeqNo());
        Helper.setDefaultAddValue(saleOrderScan, fuserid);
        // 新增销售扫描记录
        saleOrderScanMapper.insert(saleOrderScan);
        // 修改发货数量
        saleOrderBllMapper.update(
                new SaleOrderBll(),
                Wrappers.<SaleOrderBll>lambdaUpdate()
                        .setSql("fScanNum = fScanNum + 1")
                        .eq(SaleOrderBll::getfDtlId, scan.getfSaleOrderCode())
                        .eq(SaleOrderBll::getfSeqNo, scan.getfSeqNo())
        );
    }

    @Override
    public SalesOrderShow selSalesOrderByFId(String fId) {
        return salesOrderMapper.selSalesOrderByFId(fId);
    }

    @Override
    @Transactional
    public int updateSalesOrderByFId(SalesOrderUpdateDto salesOrderUpdateDto) throws Exception {
        Helper.setEmptyWithNull(salesOrderUpdateDto);
        int count = salesOrderMapper.selCountByOrderState(salesOrderUpdateDto.getfId(), OrderType.DRAFT);
        if (count == 0)
            throw new BusinessException(HttpStatus.BAD_REQUEST, "不是草稿状态，不能修改！！");
        salesOrderUpdateDto.setfLastModifyTime(LocalDateTime.now());
        salesOrderUpdateDto.setfLastModifyUserId(loginUserRedisService.getUser().getFuserid());
        return salesOrderMapper.updateSalesOrderByFId(salesOrderUpdateDto);
    }

    @Override
    @Transactional
    public int updateProductNumType(String bar) throws Exception {
        Map<String, Object> upt = new HashMap<>(4);
        upt.put("processing", ProductType.SCAN);
        upt.put("scan", bar);
        upt.put("modify", loginUserRedisService.getUser().getFuserid());
        upt.put("time", LocalDateTime.now());
        return productNumberMapper.updateProTypeByBarCode(upt);
    }


}
